package xyz.ssf.cloud.project.system.controller;

import cn.hutool.core.bean.BeanUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import xyz.ssf.cloud.common.core.domain.R;
import xyz.ssf.cloud.common.utils.HashUtils;
import xyz.ssf.cloud.project.system.domain.SysUser;
import xyz.ssf.cloud.project.system.domain.User;
import xyz.ssf.cloud.project.system.domain.vo.LoginUserVo;
import xyz.ssf.cloud.project.system.service.ISysLoginService;
import xyz.ssf.cloud.project.system.service.ISysUserService;
import xyz.ssf.cloud.project.system.service.IUserService;

import java.util.HashMap;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;

/**
 * 用户登录控制器
 * 
 * @author ssf
 */
@RestController
@RequestMapping("/user")
@Slf4j
public class LoginController {
    
    @Autowired
    private ISysLoginService loginService;
    
    @Autowired
    private IUserService userService;

    /**
     * 用户登录
     * 
     * @param telephone 登录电话
     * @param password 登录密码
     * @return 结果
     */
    @PostMapping("/login")
    public R<Map<String, Object>> login(String telephone, String password) {
        log.info("接收到登录请求: telephone={}", telephone);
        
        // 参数校验
        if (StringUtils.isAnyBlank(telephone, password)) {
            log.warn("登录失败: 手机号或密码为空");
            return R.error("手机号或密码不能为空");
        }

        // 获取用户信息
        User user = userService.selectUserByTelephone(telephone);
        if (user == null) {
            log.warn("登录失败: 用户不存在, telephone={}", telephone);
            return R.error("手机号或密码错误");
        }
        
        // 获取盐值和数据库密码
        String salt = user.getSalt();
        String dbPassword = user.getPassword();
        log.info("用户信息: userId={}, telephone={}, salt={}", user.getUserId(), telephone, salt);
        
        // 使用旧系统格式的密码哈希计算
        String legacyHash = HashUtils.legacyPasswordHash(password, salt);
        log.info("旧系统格式哈希: {}", legacyHash);
        
        // 首先尝试使用标准/常见的哈希格式
        if (dbPassword.equals(legacyHash)) {
            log.info("密码匹配成功: 使用旧系统标准格式 (MD5+盐+1024次迭代)");
        } else {
            // 如果标准格式不匹配，尝试兼容性哈希
            log.info("标准格式密码不匹配，尝试兼容性哈希");
            boolean passwordMatch = HashUtils.compatibleMatches(password, dbPassword, salt);
            
            if (!passwordMatch) {
                // 输出更多详细信息用于调试
                String[] allPossibleHashes = HashUtils.compatibleHash(password, salt);
                log.warn("密码验证失败: 数据库密码={}", dbPassword);
                for (int i = 0; i < allPossibleHashes.length; i++) {
                    if (allPossibleHashes[i] != null) {
                        log.info("尝试的哈希 #{}: {}", i+1, allPossibleHashes[i]);
                    }
                }
                return R.error("手机号或密码错误");
            } else {
                log.info("密码匹配成功: 使用兼容性哈希");
            }
        }
        
        // 判断用户状态 available(0-不可用,1-可用)
        if (user.getAvailable() != null && user.getAvailable() == 0) {
            log.warn("登录失败: 账号已停用, userId={}", user.getUserId());
            return R.error("账号已停用，请联系管理员");
        }
        
        // 生成token
        Map<String, Object> param = new HashMap<>();
        param.put("userId", user.getUserId());
        String token = loginService.generateToken(param);
        log.info("生成token成功: {}", token);
        
        // 创建系统用户对象
        SysUser sysUser = new SysUser();
        sysUser.id = Long.valueOf(user.getUserId());
        sysUser.username = user.getUsername();
        sysUser.password = user.getPassword();
        sysUser.mobile = user.getTelephone();
        sysUser.email = user.getEmail();
        sysUser.salt = user.getSalt();
        sysUser.status = user.getAvailable() == 1 ? "0" : "1"; // 转换状态值(0-正常，1-停用)
        sysUser.avatar = user.getImageUrl();
        sysUser.loginDate = null; // 暂时不设置
        sysUser.gender = user.getSex();
        
        // 组装返回数据
        LoginUserVo loginUser = loginService.createLoginUser(sysUser);
        Map<String, Object> result = new HashMap<>();
        result.put("user", loginUser.user);
        result.put("token", "Bearer " + token);
        
        log.info("用户登录成功: username={}, userId={}", user.getUsername(), user.getUserId());
        return R.success("登录成功", result);
    }
    
    /**
     * 获取用户信息
     * 
     * @return 用户信息
     */
    @GetMapping("/info")
    public R<Map<String, Object>> getInfo(@RequestHeader("token") String token) {
        if (StringUtils.isEmpty(token)) {
            return R.error("未提供token");
        }
        
        String userId = userService.getUserIdByToken(token);
        
        if (StringUtils.isEmpty(userId)) {
            return R.error("用户暂未登录");
        }
        
        // 获取登录用户信息
        LoginUserVo loginUser = loginService.getLoginUser();
        
        // 组装返回数据
        Map<String, Object> result = new HashMap<>();
        result.put("user", loginUser.user);
        result.put("roles", loginUser.roles);
        result.put("permissions", loginUser.permissions);
        
        return R.success(result);
    }
    
    /**
     * 获取验证码
     * 
     * @return 验证码信息
     */
    @GetMapping("/captcha")
    public R<Object> getCaptcha() {
        Object captcha = loginService.getCaptcha();
        return R.success("操作成功", captcha);
    }
    
    /**
     * 退出登录
     * 
     * @return 结果
     */
    @PostMapping("/logout")
    public R<Void> logout() {
        loginService.logout();
        return R.success("退出成功");
    }
} 